package com.atguigu.gulimall.search.thread;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * day89：
 *      CompletableFuture测试
 * Create by koala on 2021-05-04
 */
public class ThreadTest {

    public static ExecutorService executor = Executors.newFixedThreadPool(10);

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
            System.out.println("当前线程：" + Thread.currentThread().getId());
            int i = 10 / 2;
            System.out.println("运行结果：" + i);
        },executor);

        CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> {
            System.out.println("当前线程：" + Thread.currentThread().getId());
            int i = 10 / 2;
            System.out.println("运行结果：" + i);
            return i;
        },executor);
        Integer integer = future2.get();
        System.out.println("supplyAsync运行结果：" + integer);

        //方法执行完成后的感知
        CompletableFuture<Integer> future3 = CompletableFuture.supplyAsync(() -> {
            System.out.println("当前线程：" + Thread.currentThread().getId());
            int i = 10 / 0;
            System.out.println("运行结果：" + i);
            return i;
        },executor).whenComplete((res, exception) -> {
            //虽然能得到异常信息，但是没法修改返回数据
            System.out.println("异步任务成功完成了...结果是：" + res + ";异常是：" + exception);
        }).exceptionally(throwable -> {
            //可以感知异常，同时返回默认值
            return 10;
        });
        Integer integer2 = future3.get();
        System.out.println("supplyAsync运行结果：" + integer2);

        //方法执行完成后的处理
        CompletableFuture<Integer> future4 = CompletableFuture.supplyAsync(() -> {
            System.out.println("当前线程：" + Thread.currentThread().getId());
            int i = 10 / 0;
            System.out.println("运行结果：" + i);
            return i;
        },executor).handle((res, thr) -> {
            if(res != null){
                return res * 2;
            }
            if(thr != null){
                return 0;
            }
            return 0;
        });
        Integer integer3 = future4.get();
        System.out.println("supplyAsync运行结果：" + integer3);

        /**
         * 线程串行化
         * 1）、thenRunAsync：不能获取到上一步的执行结果，无返回值
         * 2）、thenAcceptAsync：能接受上一步结果，无返回值
         * 3）、thenApplyAsync：能接受上一步结果，有返回值
         */
        CompletableFuture<Void> future5 = CompletableFuture.supplyAsync(() -> {
            System.out.println("当前线程：" + Thread.currentThread().getId());
            int i = 10 / 2;
            System.out.println("运行结果：" + i);
            return i;
        },executor).thenRunAsync(() -> {
            System.out.println("任务1启动了...");
        },executor);

        CompletableFuture<Void> future6 = CompletableFuture.supplyAsync(() -> {
            System.out.println("当前线程：" + Thread.currentThread().getId());
            int i = 10 / 2;
            System.out.println("运行结果：" + i);
            return i;
        },executor).thenAcceptAsync(res -> {
            System.out.println("任务2启动了..." + res);
        },executor);

        CompletableFuture<String> future7 = CompletableFuture.supplyAsync(() -> {
            System.out.println("当前线程：" + Thread.currentThread().getId());
            int i = 10 / 2;
            System.out.println("运行结果：" + i);
            return i;
        },executor).thenApplyAsync(res -> {
            System.out.println("任务3启动了..." + res);
            return "Hello " + res;
        },executor);
        System.out.println("future7执行结果：" + future7.get());

        /**
         * 两个都完成
         */
        CompletableFuture<Integer> future01 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务1线程：" + Thread.currentThread().getId());
            int i = 10 / 2;
            System.out.println("任务1结束：");
            return i;
        },executor);

        CompletableFuture<String> future02 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务2线程：" + Thread.currentThread().getId());
            System.out.println("任务2结束：");
            return "Hello";
        },executor);

        future01.runAfterBothAsync(future02,() -> {
            System.out.println("任务3开始...");
        },executor);

        future01.thenAcceptBothAsync(future02,(f1, f2) -> {
            System.out.println("任务3开始...之前的结果：" + f1 + "-->" + f2);
        },executor);

        CompletableFuture<String> future03 = future01.thenCombineAsync(future02, (f1, f2) -> {
            return f1 + "：" + f2 + " -> haha";
        }, executor);

        System.out.println("future03的结果：" + future03.get());

        /**
         * 两个任务，只要有一个完成，我们就执行任务3
         * 1）、runAfterEitherAsync：不感知结果，自己没有返回值
         * 2）、acceptEitherAsync：感知结果，自己没有返回值
         * 3）、applyToEitherAsync：感知结果，自己有返回值
         */
        /*CompletableFuture<Object> futureTask01 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务1线程：" + Thread.currentThread().getId());
            int i = 10 / 2;
            System.out.println("任务1结束：");
            return i;
        },executor);

        CompletableFuture<Object> futureTask02 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务2线程：" + Thread.currentThread().getId());
            try {
                Thread.sleep(3000);
                System.out.println("任务2结束：");
            }catch (InterruptedException e){
                e.printStackTrace();
            }
            return "Hello";
        },executor);

        futureTask01.runAfterEitherAsync(futureTask02,()->{
            System.out.println("任务3开始啦。。。");
        },executor);

        futureTask01.acceptEitherAsync(futureTask02,(res) -> {
            System.out.println("任务2开始...之前的结果是：" + res);
        },executor);

        CompletableFuture<String> stringCompletableFuture = futureTask01.applyToEitherAsync(futureTask02, (res) -> {
            System.out.println("任务2开始...之前的结果是：" + res);
            return res.toString() + " -> 哈哈";
        }, executor);

        System.out.println("stringCompletableFuture的结果是：" + stringCompletableFuture.get());*/

        /**
         * allOf：等待所有任务完成
         * anyOf：只要有一个任务完成
         */
        CompletableFuture<String> futureImg = CompletableFuture.supplyAsync(() -> {
            System.out.println("查询商品的图片信息");
            return "hello.jpg";
        }, executor);

        CompletableFuture<String> futureAttr = CompletableFuture.supplyAsync(() -> {
            System.out.println("查询商品的属性");
            return "黑色+256G";
        }, executor);

        CompletableFuture<String> futureDesc = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(3000);
                System.out.println("查询商品介绍");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "华为";
        }, executor);

        CompletableFuture<Void> allOf = CompletableFuture.allOf(futureImg, futureAttr, futureDesc);
        allOf.get();//等待所有结果完成
        System.out.println(futureImg.get() + "-->" + futureAttr.get() + "-->" + futureDesc.get());

        CompletableFuture<Object> anyOf = CompletableFuture.anyOf(futureImg, futureAttr, futureDesc);
        System.out.println("anyOf的结果是：" + anyOf.get());
    }

}
